@dxos/ui-editor 0.10.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (551) hide show
  1. package/dist/lib/chunk-diff.mjs +935 -0
  2. package/dist/lib/chunk-diff.mjs.map +1 -0
  3. package/dist/lib/headless.mjs +2 -0
  4. package/dist/lib/index.mjs +9937 -0
  5. package/dist/lib/index.mjs.map +1 -0
  6. package/dist/lib/types.mjs +18 -0
  7. package/dist/lib/types.mjs.map +1 -0
  8. package/dist/types/src/extensions/{bookmarks.d.ts → behavior/bookmarks.d.ts} +3 -0
  9. package/dist/types/src/extensions/behavior/bookmarks.d.ts.map +1 -0
  10. package/dist/types/src/extensions/behavior/dnd.d.ts.map +1 -0
  11. package/dist/types/src/extensions/behavior/index.d.ts +6 -0
  12. package/dist/types/src/extensions/behavior/index.d.ts.map +1 -0
  13. package/dist/types/src/extensions/{listener.d.ts → behavior/listener.d.ts} +3 -0
  14. package/dist/types/src/extensions/behavior/listener.d.ts.map +1 -0
  15. package/dist/types/src/extensions/{spacing.d.ts → behavior/spacing.d.ts} +3 -0
  16. package/dist/types/src/extensions/behavior/spacing.d.ts.map +1 -0
  17. package/dist/types/src/extensions/behavior/submit.d.ts.map +1 -0
  18. package/dist/types/src/extensions/collab/automerge/automerge.d.ts.map +1 -0
  19. package/dist/types/src/extensions/collab/automerge/automerge.test.d.ts.map +1 -0
  20. package/dist/types/src/extensions/{automerge → collab/automerge}/cursor.d.ts +1 -1
  21. package/dist/types/src/extensions/collab/automerge/cursor.d.ts.map +1 -0
  22. package/dist/types/src/extensions/{automerge → collab/automerge}/defs.d.ts +3 -1
  23. package/dist/types/src/extensions/collab/automerge/defs.d.ts.map +1 -0
  24. package/dist/types/src/extensions/collab/automerge/index.d.ts +3 -0
  25. package/dist/types/src/extensions/collab/automerge/index.d.ts.map +1 -0
  26. package/dist/types/src/extensions/collab/automerge/sync.d.ts.map +1 -0
  27. package/dist/types/src/extensions/{automerge → collab/automerge}/update-automerge.d.ts +4 -0
  28. package/dist/types/src/extensions/collab/automerge/update-automerge.d.ts.map +1 -0
  29. package/dist/types/src/extensions/{automerge → collab/automerge}/update-codemirror.d.ts +4 -0
  30. package/dist/types/src/extensions/collab/automerge/update-codemirror.d.ts.map +1 -0
  31. package/dist/types/src/extensions/collab/awareness/awareness-provider.d.ts.map +1 -0
  32. package/dist/types/src/extensions/{awareness → collab/awareness}/awareness.d.ts +4 -1
  33. package/dist/types/src/extensions/collab/awareness/awareness.d.ts.map +1 -0
  34. package/dist/types/src/extensions/collab/awareness/index.d.ts.map +1 -0
  35. package/dist/types/src/extensions/collab/index.d.ts +3 -0
  36. package/dist/types/src/extensions/collab/index.d.ts.map +1 -0
  37. package/dist/types/src/extensions/completion/autocomplete.d.ts.map +1 -0
  38. package/dist/types/src/extensions/{autocomplete → completion}/index.d.ts +1 -0
  39. package/dist/types/src/extensions/completion/index.d.ts.map +1 -0
  40. package/dist/types/src/extensions/{autocomplete → completion}/match.d.ts +2 -2
  41. package/dist/types/src/extensions/completion/match.d.ts.map +1 -0
  42. package/dist/types/src/extensions/{mention.d.ts → completion/mention.d.ts} +3 -0
  43. package/dist/types/src/extensions/completion/mention.d.ts.map +1 -0
  44. package/dist/types/src/extensions/completion/placeholder.d.ts.map +1 -0
  45. package/dist/types/src/extensions/{autocomplete → completion}/typeahead.d.ts +2 -2
  46. package/dist/types/src/extensions/completion/typeahead.d.ts.map +1 -0
  47. package/dist/types/src/extensions/{factories.d.ts → core/factories.d.ts} +23 -2
  48. package/dist/types/src/extensions/core/factories.d.ts.map +1 -0
  49. package/dist/types/src/extensions/core/factories.test.d.ts.map +1 -0
  50. package/dist/types/src/extensions/core/index.d.ts +3 -0
  51. package/dist/types/src/extensions/core/index.d.ts.map +1 -0
  52. package/dist/types/src/extensions/{modes.d.ts → core/modes.d.ts} +3 -0
  53. package/dist/types/src/extensions/core/modes.d.ts.map +1 -0
  54. package/dist/types/src/extensions/{debug.d.ts → debug/debug.d.ts} +3 -0
  55. package/dist/types/src/extensions/debug/debug.d.ts.map +1 -0
  56. package/dist/types/src/extensions/debug/index.d.ts +2 -0
  57. package/dist/types/src/extensions/debug/index.d.ts.map +1 -0
  58. package/dist/types/src/extensions/{annotations.d.ts → decoration/annotations.d.ts} +1 -1
  59. package/dist/types/src/extensions/decoration/annotations.d.ts.map +1 -0
  60. package/dist/types/src/extensions/decoration/assistant.d.ts +27 -0
  61. package/dist/types/src/extensions/decoration/assistant.d.ts.map +1 -0
  62. package/dist/types/src/extensions/decoration/fader.d.ts.map +1 -0
  63. package/dist/types/src/extensions/decoration/hashtag.d.ts +6 -0
  64. package/dist/types/src/extensions/decoration/hashtag.d.ts.map +1 -0
  65. package/dist/types/src/extensions/decoration/index.d.ts +8 -0
  66. package/dist/types/src/extensions/decoration/index.d.ts.map +1 -0
  67. package/dist/types/src/extensions/decoration/marker.d.ts.map +1 -0
  68. package/dist/types/src/extensions/{pos.d.ts → decoration/pos.d.ts} +40 -14
  69. package/dist/types/src/extensions/decoration/pos.d.ts.map +1 -0
  70. package/dist/types/src/extensions/decoration/pos.test.d.ts.map +1 -0
  71. package/dist/types/src/extensions/{replacer.d.ts → decoration/replacer.d.ts} +8 -8
  72. package/dist/types/src/extensions/decoration/replacer.d.ts.map +1 -0
  73. package/dist/types/src/extensions/decoration/replacer.test.d.ts.map +1 -0
  74. package/dist/types/src/extensions/{blast.d.ts → demo/blast.d.ts} +3 -0
  75. package/dist/types/src/extensions/demo/blast.d.ts.map +1 -0
  76. package/dist/types/src/extensions/demo/index.d.ts +3 -0
  77. package/dist/types/src/extensions/demo/index.d.ts.map +1 -0
  78. package/dist/types/src/extensions/demo/snippets.d.ts.map +1 -0
  79. package/dist/types/src/extensions/index.d.ts +10 -33
  80. package/dist/types/src/extensions/index.d.ts.map +1 -1
  81. package/dist/types/src/extensions/language/index.d.ts +5 -0
  82. package/dist/types/src/extensions/language/index.d.ts.map +1 -0
  83. package/dist/types/src/extensions/language/json/index.d.ts +2 -0
  84. package/dist/types/src/extensions/language/json/index.d.ts.map +1 -0
  85. package/dist/types/src/extensions/language/json/json.d.ts +12 -0
  86. package/dist/types/src/extensions/language/json/json.d.ts.map +1 -0
  87. package/dist/types/src/extensions/language/markdown/action.d.ts.map +1 -0
  88. package/dist/types/src/extensions/language/markdown/bundle.d.ts.map +1 -0
  89. package/dist/types/src/extensions/{markdown → language/markdown}/changes.d.ts +1 -1
  90. package/dist/types/src/extensions/language/markdown/changes.d.ts.map +1 -0
  91. package/dist/types/src/extensions/language/markdown/changes.test.d.ts.map +1 -0
  92. package/dist/types/src/extensions/{markdown → language/markdown}/debug.d.ts +3 -0
  93. package/dist/types/src/extensions/language/markdown/debug.d.ts.map +1 -0
  94. package/dist/types/src/extensions/{markdown → language/markdown}/decorate.d.ts +5 -1
  95. package/dist/types/src/extensions/language/markdown/decorate.d.ts.map +1 -0
  96. package/dist/types/src/extensions/{markdown → language/markdown}/formatting.d.ts +11 -2
  97. package/dist/types/src/extensions/language/markdown/formatting.d.ts.map +1 -0
  98. package/dist/types/src/extensions/language/markdown/formatting.test.d.ts.map +1 -0
  99. package/dist/types/src/extensions/{markdown → language/markdown}/highlight.d.ts +16 -12
  100. package/dist/types/src/extensions/language/markdown/highlight.d.ts.map +1 -0
  101. package/dist/types/src/extensions/language/markdown/image.d.ts.map +1 -0
  102. package/dist/types/src/extensions/language/markdown/image.test.d.ts.map +1 -0
  103. package/dist/types/src/extensions/language/markdown/index.d.ts.map +1 -0
  104. package/dist/types/src/extensions/language/markdown/link.d.ts +25 -0
  105. package/dist/types/src/extensions/language/markdown/link.d.ts.map +1 -0
  106. package/dist/types/src/extensions/language/markdown/link.test.d.ts +2 -0
  107. package/dist/types/src/extensions/language/markdown/link.test.d.ts.map +1 -0
  108. package/dist/types/src/extensions/language/markdown/parser.test.d.ts.map +1 -0
  109. package/dist/types/src/extensions/{markdown → language/markdown}/styles.d.ts +3 -0
  110. package/dist/types/src/extensions/language/markdown/styles.d.ts.map +1 -0
  111. package/dist/types/src/extensions/language/markdown/table.d.ts.map +1 -0
  112. package/dist/types/src/extensions/language/mermaid/index.d.ts +2 -0
  113. package/dist/types/src/extensions/language/mermaid/index.d.ts.map +1 -0
  114. package/dist/types/src/extensions/language/mermaid/mermaid.d.ts +18 -0
  115. package/dist/types/src/extensions/language/mermaid/mermaid.d.ts.map +1 -0
  116. package/dist/types/src/extensions/language/xml/extended-markdown.d.ts.map +1 -0
  117. package/dist/types/src/extensions/language/xml/extended-markdown.test.d.ts.map +1 -0
  118. package/dist/types/src/extensions/language/xml/index.d.ts.map +1 -0
  119. package/dist/types/src/extensions/language/xml/stub.d.ts +76 -0
  120. package/dist/types/src/extensions/language/xml/stub.d.ts.map +1 -0
  121. package/dist/types/src/extensions/language/xml/widgets/anchor.d.ts.map +1 -0
  122. package/dist/types/src/extensions/language/xml/widgets/index.d.ts.map +1 -0
  123. package/dist/types/src/extensions/language/xml/xml-block-decoration.d.ts +48 -0
  124. package/dist/types/src/extensions/language/xml/xml-block-decoration.d.ts.map +1 -0
  125. package/dist/types/src/extensions/language/xml/xml-formatting.d.ts.map +1 -0
  126. package/dist/types/src/extensions/{tags → language/xml}/xml-tags.d.ts +12 -1
  127. package/dist/types/src/extensions/language/xml/xml-tags.d.ts.map +1 -0
  128. package/dist/types/src/extensions/language/xml/xml-tags.test.d.ts +2 -0
  129. package/dist/types/src/extensions/language/xml/xml-tags.test.d.ts.map +1 -0
  130. package/dist/types/src/extensions/language/xml/xml-util.d.ts.map +1 -0
  131. package/dist/types/src/extensions/language/xml/xml-util.test.d.ts.map +1 -0
  132. package/dist/types/src/extensions/review/change-bar.d.ts +29 -0
  133. package/dist/types/src/extensions/review/change-bar.d.ts.map +1 -0
  134. package/dist/types/src/extensions/{comments.d.ts → review/comments.d.ts} +56 -38
  135. package/dist/types/src/extensions/review/comments.d.ts.map +1 -0
  136. package/dist/types/src/extensions/review/comments.test.d.ts +2 -0
  137. package/dist/types/src/extensions/review/comments.test.d.ts.map +1 -0
  138. package/dist/types/src/extensions/review/diff.d.ts +131 -0
  139. package/dist/types/src/extensions/review/diff.d.ts.map +1 -0
  140. package/dist/types/src/extensions/review/diff.test.d.ts +2 -0
  141. package/dist/types/src/extensions/review/diff.test.d.ts.map +1 -0
  142. package/dist/types/src/extensions/review/index.d.ts +7 -0
  143. package/dist/types/src/extensions/review/index.d.ts.map +1 -0
  144. package/dist/types/src/extensions/review/suggest.d.ts +89 -0
  145. package/dist/types/src/extensions/review/suggest.d.ts.map +1 -0
  146. package/dist/types/src/extensions/review/suggest.test.d.ts +2 -0
  147. package/dist/types/src/extensions/review/suggest.test.d.ts.map +1 -0
  148. package/dist/types/src/extensions/review/suggestions-overlay.d.ts +25 -0
  149. package/dist/types/src/extensions/review/suggestions-overlay.d.ts.map +1 -0
  150. package/dist/types/src/extensions/review/suggestions-overlay.test.d.ts +2 -0
  151. package/dist/types/src/extensions/review/suggestions-overlay.test.d.ts.map +1 -0
  152. package/dist/types/src/extensions/review/track-changes.d.ts +27 -0
  153. package/dist/types/src/extensions/review/track-changes.d.ts.map +1 -0
  154. package/dist/types/src/extensions/review/track-changes.test.d.ts +2 -0
  155. package/dist/types/src/extensions/review/track-changes.test.d.ts.map +1 -0
  156. package/dist/types/src/extensions/{busy.d.ts → state/busy.d.ts} +1 -0
  157. package/dist/types/src/extensions/state/busy.d.ts.map +1 -0
  158. package/dist/types/src/extensions/{focus.d.ts → state/focus.d.ts} +4 -0
  159. package/dist/types/src/extensions/state/focus.d.ts.map +1 -0
  160. package/dist/types/src/extensions/state/index.d.ts +5 -0
  161. package/dist/types/src/extensions/state/index.d.ts.map +1 -0
  162. package/dist/types/src/extensions/state/modal.d.ts.map +1 -0
  163. package/dist/types/src/extensions/{selection.d.ts → state/selection.d.ts} +1 -1
  164. package/dist/types/src/extensions/state/selection.d.ts.map +1 -0
  165. package/dist/types/src/extensions/state/selection.test.d.ts.map +1 -0
  166. package/dist/types/src/extensions/streaming/index.d.ts +4 -0
  167. package/dist/types/src/extensions/streaming/index.d.ts.map +1 -0
  168. package/dist/types/src/extensions/streaming/pending/index.d.ts.map +1 -0
  169. package/dist/types/src/extensions/streaming/pending/pending-text-stream.d.ts.map +1 -0
  170. package/dist/types/src/extensions/streaming/pending/pending-text-stream.test.d.ts.map +1 -0
  171. package/dist/types/src/extensions/{pending → streaming/pending}/pending-text.d.ts +1 -0
  172. package/dist/types/src/extensions/streaming/pending/pending-text.d.ts.map +1 -0
  173. package/dist/types/src/extensions/streaming/pending/pending-text.test.d.ts.map +1 -0
  174. package/dist/types/src/extensions/streaming/scrolling/auto-scroll.d.ts.map +1 -0
  175. package/dist/types/src/extensions/streaming/scrolling/crawler.d.ts.map +1 -0
  176. package/dist/types/src/extensions/streaming/scrolling/index.d.ts.map +1 -0
  177. package/dist/types/src/extensions/streaming/scrolling/scroll-past-end.d.ts +4 -0
  178. package/dist/types/src/extensions/streaming/scrolling/scroll-past-end.d.ts.map +1 -0
  179. package/dist/types/src/extensions/streaming/scrolling/scrollbar-autohide.d.ts.map +1 -0
  180. package/dist/types/src/extensions/streaming/scrolling/scroller.d.ts.map +1 -0
  181. package/dist/types/src/extensions/{typewriter.d.ts → streaming/typewriter.d.ts} +12 -12
  182. package/dist/types/src/extensions/streaming/typewriter.d.ts.map +1 -0
  183. package/dist/types/src/extensions/streaming/typewriter.test.d.ts.map +1 -0
  184. package/dist/types/src/extensions/structure/blocks/blocks.d.ts +52 -0
  185. package/dist/types/src/extensions/structure/blocks/blocks.d.ts.map +1 -0
  186. package/dist/types/src/extensions/structure/blocks/blocks.test.d.ts +2 -0
  187. package/dist/types/src/extensions/structure/blocks/blocks.test.d.ts.map +1 -0
  188. package/dist/types/src/extensions/structure/blocks/drag.d.ts +57 -0
  189. package/dist/types/src/extensions/structure/blocks/drag.d.ts.map +1 -0
  190. package/dist/types/src/extensions/structure/blocks/index.d.ts +5 -0
  191. package/dist/types/src/extensions/structure/blocks/index.d.ts.map +1 -0
  192. package/dist/types/src/extensions/structure/blocks/selection.d.ts +47 -0
  193. package/dist/types/src/extensions/structure/blocks/selection.d.ts.map +1 -0
  194. package/dist/types/src/extensions/structure/blocks/selection.test.d.ts +2 -0
  195. package/dist/types/src/extensions/structure/blocks/selection.test.d.ts.map +1 -0
  196. package/dist/types/src/extensions/structure/blocks/types.d.ts +17 -0
  197. package/dist/types/src/extensions/structure/blocks/types.d.ts.map +1 -0
  198. package/dist/types/src/extensions/structure/folding/folding.d.ts.map +1 -0
  199. package/dist/types/src/extensions/structure/folding/index.d.ts +3 -0
  200. package/dist/types/src/extensions/structure/folding/index.d.ts.map +1 -0
  201. package/dist/types/src/extensions/structure/folding/turns.d.ts +55 -0
  202. package/dist/types/src/extensions/structure/folding/turns.d.ts.map +1 -0
  203. package/dist/types/src/extensions/structure/folding/turns.test.d.ts +2 -0
  204. package/dist/types/src/extensions/structure/folding/turns.test.d.ts.map +1 -0
  205. package/dist/types/src/extensions/structure/index.d.ts +4 -0
  206. package/dist/types/src/extensions/structure/index.d.ts.map +1 -0
  207. package/dist/types/src/extensions/structure/outliner/commands.d.ts +31 -0
  208. package/dist/types/src/extensions/structure/outliner/commands.d.ts.map +1 -0
  209. package/dist/types/src/extensions/structure/outliner/dnd.d.ts +43 -0
  210. package/dist/types/src/extensions/structure/outliner/dnd.d.ts.map +1 -0
  211. package/dist/types/src/extensions/structure/outliner/dnd.test.d.ts +2 -0
  212. package/dist/types/src/extensions/structure/outliner/dnd.test.d.ts.map +1 -0
  213. package/dist/types/src/extensions/structure/outliner/editor.d.ts.map +1 -0
  214. package/dist/types/src/extensions/structure/outliner/editor.test.d.ts.map +1 -0
  215. package/dist/types/src/extensions/{outliner → structure/outliner}/index.d.ts +1 -0
  216. package/dist/types/src/extensions/structure/outliner/index.d.ts.map +1 -0
  217. package/dist/types/src/extensions/{outliner → structure/outliner}/menu.d.ts +1 -0
  218. package/dist/types/src/extensions/structure/outliner/menu.d.ts.map +1 -0
  219. package/dist/types/src/extensions/structure/outliner/outliner.d.ts.map +1 -0
  220. package/dist/types/src/extensions/structure/outliner/outliner.test.d.ts.map +1 -0
  221. package/dist/types/src/extensions/{outliner → structure/outliner}/tree.d.ts +1 -1
  222. package/dist/types/src/extensions/structure/outliner/tree.d.ts.map +1 -0
  223. package/dist/types/src/extensions/structure/outliner/tree.test.d.ts.map +1 -0
  224. package/dist/types/src/headless.d.ts +4 -0
  225. package/dist/types/src/headless.d.ts.map +1 -0
  226. package/dist/types/src/styles/theme.d.ts +1 -1
  227. package/dist/types/src/styles/theme.d.ts.map +1 -1
  228. package/dist/types/src/util/util.d.ts +2 -0
  229. package/dist/types/src/util/util.d.ts.map +1 -1
  230. package/dist/types/tsconfig.tsbuildinfo +1 -1
  231. package/package.json +48 -42
  232. package/src/defaults.ts +1 -1
  233. package/src/extensions/{bookmarks.ts → behavior/bookmarks.ts} +24 -14
  234. package/src/extensions/behavior/index.ts +9 -0
  235. package/src/extensions/{listener.ts → behavior/listener.ts} +4 -1
  236. package/src/extensions/{spacing.ts → behavior/spacing.ts} +8 -2
  237. package/src/extensions/{submit.ts → behavior/submit.ts} +2 -10
  238. package/src/extensions/{automerge → collab/automerge}/automerge.test.tsx +4 -4
  239. package/src/extensions/{automerge → collab/automerge}/automerge.ts +7 -4
  240. package/src/extensions/{automerge → collab/automerge}/cursor.ts +1 -1
  241. package/src/extensions/{automerge → collab/automerge}/defs.ts +4 -1
  242. package/src/extensions/{automerge → collab/automerge}/index.ts +1 -0
  243. package/src/extensions/{automerge → collab/automerge}/sync.ts +1 -2
  244. package/src/extensions/{automerge → collab/automerge}/update-automerge.ts +4 -0
  245. package/src/extensions/{automerge → collab/automerge}/update-codemirror.ts +5 -1
  246. package/src/extensions/{awareness → collab/awareness}/awareness-provider.ts +3 -4
  247. package/src/extensions/{awareness → collab/awareness}/awareness.ts +19 -16
  248. package/src/extensions/collab/index.ts +6 -0
  249. package/src/extensions/{autocomplete → completion}/autocomplete.ts +7 -5
  250. package/src/extensions/{autocomplete → completion}/index.ts +2 -1
  251. package/src/extensions/{autocomplete → completion}/match.ts +2 -2
  252. package/src/extensions/{mention.ts → completion/mention.ts} +3 -0
  253. package/src/extensions/{autocomplete → completion}/placeholder.ts +1 -1
  254. package/src/extensions/completion/typeahead.ts +97 -0
  255. package/src/extensions/{factories.ts → core/factories.ts} +35 -13
  256. package/src/extensions/core/index.ts +6 -0
  257. package/src/extensions/{modes.ts → core/modes.ts} +4 -1
  258. package/src/extensions/{debug.ts → debug/debug.ts} +3 -0
  259. package/src/extensions/debug/index.ts +5 -0
  260. package/src/extensions/{annotations.ts → decoration/annotations.ts} +12 -10
  261. package/src/extensions/decoration/assistant.ts +225 -0
  262. package/src/extensions/{fader.ts → decoration/fader.ts} +17 -19
  263. package/src/extensions/{hashtag.ts → decoration/hashtag.ts} +35 -28
  264. package/src/extensions/decoration/index.ts +11 -0
  265. package/src/extensions/{marker.ts → decoration/marker.ts} +18 -18
  266. package/src/extensions/{pos.test.ts → decoration/pos.test.ts} +57 -1
  267. package/src/extensions/{pos.ts → decoration/pos.ts} +165 -31
  268. package/src/extensions/{blast.ts → demo/blast.ts} +3 -0
  269. package/src/extensions/demo/index.ts +6 -0
  270. package/src/extensions/{snippets.ts → demo/snippets.ts} +5 -1
  271. package/src/extensions/index.ts +10 -33
  272. package/src/extensions/language/index.ts +8 -0
  273. package/src/extensions/language/json/index.ts +5 -0
  274. package/src/extensions/{json.ts → language/json/json.ts} +11 -6
  275. package/src/extensions/{markdown → language/markdown}/action.ts +1 -1
  276. package/src/extensions/{markdown → language/markdown}/bundle.ts +7 -1
  277. package/src/extensions/{markdown → language/markdown}/changes.test.ts +2 -2
  278. package/src/extensions/{markdown → language/markdown}/changes.ts +2 -2
  279. package/src/extensions/{markdown → language/markdown}/debug.ts +3 -0
  280. package/src/extensions/{markdown → language/markdown}/decorate.ts +96 -85
  281. package/src/extensions/{markdown → language/markdown}/formatting.test.ts +88 -1
  282. package/src/extensions/{markdown → language/markdown}/formatting.ts +193 -74
  283. package/src/extensions/{markdown → language/markdown}/highlight.ts +42 -41
  284. package/src/extensions/{markdown → language/markdown}/image.test.ts +1 -1
  285. package/src/extensions/{markdown → language/markdown}/image.ts +6 -6
  286. package/src/extensions/language/markdown/link.test.ts +58 -0
  287. package/src/extensions/language/markdown/link.ts +109 -0
  288. package/src/extensions/{markdown → language/markdown}/parser.test.ts +0 -28
  289. package/src/extensions/{markdown → language/markdown}/styles.ts +38 -7
  290. package/src/extensions/{markdown → language/markdown}/table.ts +5 -5
  291. package/src/extensions/language/mermaid/index.ts +5 -0
  292. package/src/extensions/language/mermaid/mermaid.ts +44 -0
  293. package/src/extensions/{tags → language/xml}/DESIGN.md +3 -3
  294. package/src/extensions/{tags → language/xml}/extended-markdown.test.ts +2 -1
  295. package/src/extensions/{tags → language/xml}/extended-markdown.ts +2 -4
  296. package/src/extensions/language/xml/stub.ts +233 -0
  297. package/src/extensions/language/xml/xml-block-decoration.ts +165 -0
  298. package/src/extensions/{tags → language/xml}/xml-formatting.ts +54 -38
  299. package/src/extensions/language/xml/xml-tags.test.ts +588 -0
  300. package/src/extensions/{tags → language/xml}/xml-tags.ts +165 -66
  301. package/src/extensions/{tags → language/xml}/xml-util.test.ts +2 -2
  302. package/src/extensions/review/change-bar.ts +94 -0
  303. package/src/extensions/review/comments.test.ts +72 -0
  304. package/src/extensions/{comments.ts → review/comments.ts} +395 -267
  305. package/src/extensions/review/diff.test.ts +405 -0
  306. package/src/extensions/review/diff.ts +502 -0
  307. package/src/extensions/review/index.ts +10 -0
  308. package/src/extensions/review/suggest.test.ts +170 -0
  309. package/src/extensions/review/suggest.ts +512 -0
  310. package/src/extensions/review/suggestions-overlay.test.ts +58 -0
  311. package/src/extensions/review/suggestions-overlay.ts +50 -0
  312. package/src/extensions/review/track-changes.test.ts +101 -0
  313. package/src/extensions/review/track-changes.ts +215 -0
  314. package/src/extensions/{busy.ts → state/busy.ts} +1 -0
  315. package/src/extensions/{focus.ts → state/focus.ts} +4 -0
  316. package/src/extensions/state/index.ts +8 -0
  317. package/src/extensions/{selection.ts → state/selection.ts} +3 -3
  318. package/src/extensions/streaming/index.ts +7 -0
  319. package/src/extensions/{pending → streaming/pending}/pending-text-stream.ts +10 -3
  320. package/src/extensions/{pending → streaming/pending}/pending-text.test.ts +1 -1
  321. package/src/extensions/{pending → streaming/pending}/pending-text.ts +20 -19
  322. package/src/extensions/{scrolling → streaming/scrolling}/auto-scroll.ts +9 -6
  323. package/src/extensions/{scrolling → streaming/scrolling}/scroll-past-end.ts +1 -0
  324. package/src/extensions/{scrolling → streaming/scrolling}/scrollbar-autohide.ts +13 -11
  325. package/src/extensions/{typewriter.ts → streaming/typewriter.ts} +46 -47
  326. package/src/extensions/structure/blocks/DESIGN.md +134 -0
  327. package/src/extensions/structure/blocks/blocks.test.ts +147 -0
  328. package/src/extensions/structure/blocks/blocks.ts +219 -0
  329. package/src/extensions/structure/blocks/drag.ts +996 -0
  330. package/src/extensions/structure/blocks/index.ts +8 -0
  331. package/src/extensions/structure/blocks/selection.test.ts +56 -0
  332. package/src/extensions/structure/blocks/selection.ts +279 -0
  333. package/src/extensions/structure/blocks/types.ts +22 -0
  334. package/src/extensions/{folding.ts → structure/folding/folding.ts} +12 -10
  335. package/src/extensions/structure/folding/index.ts +6 -0
  336. package/src/extensions/structure/folding/turns.test.ts +72 -0
  337. package/src/extensions/structure/folding/turns.ts +209 -0
  338. package/src/extensions/structure/index.ts +7 -0
  339. package/src/extensions/structure/outliner/DESIGN.md +183 -0
  340. package/src/extensions/structure/outliner/SPEC.mdl +305 -0
  341. package/src/extensions/{outliner → structure/outliner}/commands.ts +125 -42
  342. package/src/extensions/structure/outliner/dnd.test.ts +142 -0
  343. package/src/extensions/structure/outliner/dnd.ts +375 -0
  344. package/src/extensions/structure/outliner/editor.test.ts +85 -0
  345. package/src/extensions/{outliner → structure/outliner}/editor.ts +14 -9
  346. package/src/extensions/{outliner → structure/outliner}/index.ts +1 -0
  347. package/src/extensions/{outliner → structure/outliner}/menu.ts +48 -25
  348. package/src/extensions/structure/outliner/outliner.test.ts +193 -0
  349. package/src/extensions/structure/outliner/outliner.ts +183 -0
  350. package/src/extensions/{outliner → structure/outliner}/tree.test.ts +2 -2
  351. package/src/extensions/{outliner → structure/outliner}/tree.ts +1 -1
  352. package/src/headless.ts +13 -0
  353. package/src/styles/theme.ts +3 -1
  354. package/src/util/util.ts +3 -0
  355. package/dist/lib/browser/index.mjs +0 -9594
  356. package/dist/lib/browser/index.mjs.map +0 -7
  357. package/dist/lib/browser/meta.json +0 -1
  358. package/dist/lib/browser/types/index.mjs +0 -33
  359. package/dist/lib/browser/types/index.mjs.map +0 -7
  360. package/dist/lib/node-esm/index.mjs +0 -9596
  361. package/dist/lib/node-esm/index.mjs.map +0 -7
  362. package/dist/lib/node-esm/meta.json +0 -1
  363. package/dist/lib/node-esm/types/index.mjs +0 -35
  364. package/dist/lib/node-esm/types/index.mjs.map +0 -7
  365. package/dist/types/src/extensions/annotations.d.ts.map +0 -1
  366. package/dist/types/src/extensions/autocomplete/autocomplete.d.ts.map +0 -1
  367. package/dist/types/src/extensions/autocomplete/index.d.ts.map +0 -1
  368. package/dist/types/src/extensions/autocomplete/match.d.ts.map +0 -1
  369. package/dist/types/src/extensions/autocomplete/placeholder.d.ts.map +0 -1
  370. package/dist/types/src/extensions/autocomplete/typeahead.d.ts.map +0 -1
  371. package/dist/types/src/extensions/automerge/automerge.d.ts.map +0 -1
  372. package/dist/types/src/extensions/automerge/automerge.test.d.ts.map +0 -1
  373. package/dist/types/src/extensions/automerge/cursor.d.ts.map +0 -1
  374. package/dist/types/src/extensions/automerge/defs.d.ts.map +0 -1
  375. package/dist/types/src/extensions/automerge/index.d.ts +0 -2
  376. package/dist/types/src/extensions/automerge/index.d.ts.map +0 -1
  377. package/dist/types/src/extensions/automerge/sync.d.ts.map +0 -1
  378. package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +0 -1
  379. package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +0 -1
  380. package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +0 -1
  381. package/dist/types/src/extensions/awareness/awareness.d.ts.map +0 -1
  382. package/dist/types/src/extensions/awareness/index.d.ts.map +0 -1
  383. package/dist/types/src/extensions/blast.d.ts.map +0 -1
  384. package/dist/types/src/extensions/blocks.d.ts +0 -2
  385. package/dist/types/src/extensions/blocks.d.ts.map +0 -1
  386. package/dist/types/src/extensions/bookmarks.d.ts.map +0 -1
  387. package/dist/types/src/extensions/busy.d.ts.map +0 -1
  388. package/dist/types/src/extensions/comments.d.ts.map +0 -1
  389. package/dist/types/src/extensions/debug.d.ts.map +0 -1
  390. package/dist/types/src/extensions/dnd.d.ts.map +0 -1
  391. package/dist/types/src/extensions/factories.d.ts.map +0 -1
  392. package/dist/types/src/extensions/factories.test.d.ts.map +0 -1
  393. package/dist/types/src/extensions/fader.d.ts.map +0 -1
  394. package/dist/types/src/extensions/focus.d.ts.map +0 -1
  395. package/dist/types/src/extensions/folding.d.ts.map +0 -1
  396. package/dist/types/src/extensions/hashtag.d.ts +0 -3
  397. package/dist/types/src/extensions/hashtag.d.ts.map +0 -1
  398. package/dist/types/src/extensions/json.d.ts +0 -7
  399. package/dist/types/src/extensions/json.d.ts.map +0 -1
  400. package/dist/types/src/extensions/listener.d.ts.map +0 -1
  401. package/dist/types/src/extensions/markdown/action.d.ts.map +0 -1
  402. package/dist/types/src/extensions/markdown/bundle.d.ts.map +0 -1
  403. package/dist/types/src/extensions/markdown/changes.d.ts.map +0 -1
  404. package/dist/types/src/extensions/markdown/changes.test.d.ts.map +0 -1
  405. package/dist/types/src/extensions/markdown/debug.d.ts.map +0 -1
  406. package/dist/types/src/extensions/markdown/decorate.d.ts.map +0 -1
  407. package/dist/types/src/extensions/markdown/formatting.d.ts.map +0 -1
  408. package/dist/types/src/extensions/markdown/formatting.test.d.ts.map +0 -1
  409. package/dist/types/src/extensions/markdown/highlight.d.ts.map +0 -1
  410. package/dist/types/src/extensions/markdown/image.d.ts.map +0 -1
  411. package/dist/types/src/extensions/markdown/image.test.d.ts.map +0 -1
  412. package/dist/types/src/extensions/markdown/index.d.ts.map +0 -1
  413. package/dist/types/src/extensions/markdown/link.d.ts +0 -7
  414. package/dist/types/src/extensions/markdown/link.d.ts.map +0 -1
  415. package/dist/types/src/extensions/markdown/parser.test.d.ts.map +0 -1
  416. package/dist/types/src/extensions/markdown/styles.d.ts.map +0 -1
  417. package/dist/types/src/extensions/markdown/table.d.ts.map +0 -1
  418. package/dist/types/src/extensions/marker.d.ts.map +0 -1
  419. package/dist/types/src/extensions/mention.d.ts.map +0 -1
  420. package/dist/types/src/extensions/modal.d.ts.map +0 -1
  421. package/dist/types/src/extensions/modes.d.ts.map +0 -1
  422. package/dist/types/src/extensions/outliner/commands.d.ts +0 -10
  423. package/dist/types/src/extensions/outliner/commands.d.ts.map +0 -1
  424. package/dist/types/src/extensions/outliner/editor.d.ts.map +0 -1
  425. package/dist/types/src/extensions/outliner/editor.test.d.ts.map +0 -1
  426. package/dist/types/src/extensions/outliner/index.d.ts.map +0 -1
  427. package/dist/types/src/extensions/outliner/menu.d.ts.map +0 -1
  428. package/dist/types/src/extensions/outliner/outliner.d.ts.map +0 -1
  429. package/dist/types/src/extensions/outliner/outliner.test.d.ts.map +0 -1
  430. package/dist/types/src/extensions/outliner/selection.d.ts +0 -12
  431. package/dist/types/src/extensions/outliner/selection.d.ts.map +0 -1
  432. package/dist/types/src/extensions/outliner/tree.d.ts.map +0 -1
  433. package/dist/types/src/extensions/outliner/tree.test.d.ts.map +0 -1
  434. package/dist/types/src/extensions/pending/index.d.ts.map +0 -1
  435. package/dist/types/src/extensions/pending/pending-text-stream.d.ts.map +0 -1
  436. package/dist/types/src/extensions/pending/pending-text-stream.test.d.ts.map +0 -1
  437. package/dist/types/src/extensions/pending/pending-text.d.ts.map +0 -1
  438. package/dist/types/src/extensions/pending/pending-text.test.d.ts.map +0 -1
  439. package/dist/types/src/extensions/pos.d.ts.map +0 -1
  440. package/dist/types/src/extensions/pos.test.d.ts.map +0 -1
  441. package/dist/types/src/extensions/replacer.d.ts.map +0 -1
  442. package/dist/types/src/extensions/replacer.test.d.ts.map +0 -1
  443. package/dist/types/src/extensions/scrolling/auto-scroll.d.ts.map +0 -1
  444. package/dist/types/src/extensions/scrolling/crawler.d.ts.map +0 -1
  445. package/dist/types/src/extensions/scrolling/index.d.ts.map +0 -1
  446. package/dist/types/src/extensions/scrolling/scroll-past-end.d.ts +0 -3
  447. package/dist/types/src/extensions/scrolling/scroll-past-end.d.ts.map +0 -1
  448. package/dist/types/src/extensions/scrolling/scrollbar-autohide.d.ts.map +0 -1
  449. package/dist/types/src/extensions/scrolling/scroller.d.ts.map +0 -1
  450. package/dist/types/src/extensions/selection.d.ts.map +0 -1
  451. package/dist/types/src/extensions/selection.test.d.ts.map +0 -1
  452. package/dist/types/src/extensions/snippets.d.ts.map +0 -1
  453. package/dist/types/src/extensions/spacing.d.ts.map +0 -1
  454. package/dist/types/src/extensions/state.d.ts +0 -2
  455. package/dist/types/src/extensions/state.d.ts.map +0 -1
  456. package/dist/types/src/extensions/submit.d.ts.map +0 -1
  457. package/dist/types/src/extensions/tags/extended-markdown.d.ts.map +0 -1
  458. package/dist/types/src/extensions/tags/extended-markdown.test.d.ts.map +0 -1
  459. package/dist/types/src/extensions/tags/index.d.ts.map +0 -1
  460. package/dist/types/src/extensions/tags/stub.d.ts +0 -35
  461. package/dist/types/src/extensions/tags/stub.d.ts.map +0 -1
  462. package/dist/types/src/extensions/tags/widgets/anchor.d.ts.map +0 -1
  463. package/dist/types/src/extensions/tags/widgets/index.d.ts.map +0 -1
  464. package/dist/types/src/extensions/tags/xml-block-decoration.d.ts +0 -31
  465. package/dist/types/src/extensions/tags/xml-block-decoration.d.ts.map +0 -1
  466. package/dist/types/src/extensions/tags/xml-formatting.d.ts.map +0 -1
  467. package/dist/types/src/extensions/tags/xml-tags.d.ts.map +0 -1
  468. package/dist/types/src/extensions/tags/xml-util.d.ts.map +0 -1
  469. package/dist/types/src/extensions/tags/xml-util.test.d.ts.map +0 -1
  470. package/dist/types/src/extensions/typewriter.d.ts.map +0 -1
  471. package/dist/types/src/extensions/typewriter.test.d.ts.map +0 -1
  472. package/src/extensions/autocomplete/typeahead.ts +0 -87
  473. package/src/extensions/blocks.ts +0 -131
  474. package/src/extensions/markdown/link.ts +0 -49
  475. package/src/extensions/outliner/editor.test.ts +0 -33
  476. package/src/extensions/outliner/outliner.test.ts +0 -99
  477. package/src/extensions/outliner/outliner.ts +0 -166
  478. package/src/extensions/outliner/selection.ts +0 -50
  479. package/src/extensions/state.ts +0 -7
  480. package/src/extensions/tags/stub.ts +0 -80
  481. package/src/extensions/tags/xml-block-decoration.ts +0 -123
  482. package/dist/types/src/extensions/{dnd.d.ts → behavior/dnd.d.ts} +0 -0
  483. package/dist/types/src/extensions/{submit.d.ts → behavior/submit.d.ts} +0 -0
  484. package/dist/types/src/extensions/{automerge → collab/automerge}/automerge.d.ts +0 -0
  485. package/dist/types/src/extensions/{automerge → collab/automerge}/automerge.test.d.ts +0 -0
  486. package/dist/types/src/extensions/{automerge → collab/automerge}/sync.d.ts +0 -0
  487. package/dist/types/src/extensions/{awareness → collab/awareness}/awareness-provider.d.ts +0 -0
  488. package/dist/types/src/extensions/{awareness → collab/awareness}/index.d.ts +0 -0
  489. package/dist/types/src/extensions/{autocomplete → completion}/autocomplete.d.ts +0 -0
  490. package/dist/types/src/extensions/{autocomplete → completion}/placeholder.d.ts +0 -0
  491. package/dist/types/src/extensions/{factories.test.d.ts → core/factories.test.d.ts} +0 -0
  492. package/dist/types/src/extensions/{fader.d.ts → decoration/fader.d.ts} +0 -0
  493. package/dist/types/src/extensions/{marker.d.ts → decoration/marker.d.ts} +0 -0
  494. package/dist/types/src/extensions/{pos.test.d.ts → decoration/pos.test.d.ts} +0 -0
  495. package/dist/types/src/extensions/{replacer.test.d.ts → decoration/replacer.test.d.ts} +0 -0
  496. package/dist/types/src/extensions/{snippets.d.ts → demo/snippets.d.ts} +0 -0
  497. package/dist/types/src/extensions/{markdown → language/markdown}/action.d.ts +0 -0
  498. package/dist/types/src/extensions/{markdown → language/markdown}/bundle.d.ts +0 -0
  499. package/dist/types/src/extensions/{markdown → language/markdown}/changes.test.d.ts +0 -0
  500. package/dist/types/src/extensions/{markdown → language/markdown}/formatting.test.d.ts +0 -0
  501. package/dist/types/src/extensions/{markdown → language/markdown}/image.d.ts +0 -0
  502. package/dist/types/src/extensions/{markdown → language/markdown}/image.test.d.ts +0 -0
  503. package/dist/types/src/extensions/{markdown → language/markdown}/index.d.ts +0 -0
  504. package/dist/types/src/extensions/{markdown → language/markdown}/parser.test.d.ts +0 -0
  505. package/dist/types/src/extensions/{markdown → language/markdown}/table.d.ts +0 -0
  506. package/dist/types/src/extensions/{tags → language/xml}/extended-markdown.d.ts +0 -0
  507. package/dist/types/src/extensions/{tags → language/xml}/extended-markdown.test.d.ts +0 -0
  508. package/dist/types/src/extensions/{tags → language/xml}/index.d.ts +0 -0
  509. package/dist/types/src/extensions/{tags → language/xml}/widgets/anchor.d.ts +0 -0
  510. package/dist/types/src/extensions/{tags → language/xml}/widgets/index.d.ts +0 -0
  511. package/dist/types/src/extensions/{tags → language/xml}/xml-formatting.d.ts +0 -0
  512. package/dist/types/src/extensions/{tags → language/xml}/xml-util.d.ts +0 -0
  513. package/dist/types/src/extensions/{tags → language/xml}/xml-util.test.d.ts +0 -0
  514. package/dist/types/src/extensions/{modal.d.ts → state/modal.d.ts} +0 -0
  515. package/dist/types/src/extensions/{selection.test.d.ts → state/selection.test.d.ts} +0 -0
  516. package/dist/types/src/extensions/{pending → streaming/pending}/index.d.ts +0 -0
  517. package/dist/types/src/extensions/{pending → streaming/pending}/pending-text-stream.d.ts +0 -0
  518. package/dist/types/src/extensions/{pending → streaming/pending}/pending-text-stream.test.d.ts +0 -0
  519. package/dist/types/src/extensions/{pending → streaming/pending}/pending-text.test.d.ts +0 -0
  520. package/dist/types/src/extensions/{scrolling → streaming/scrolling}/auto-scroll.d.ts +0 -0
  521. package/dist/types/src/extensions/{scrolling → streaming/scrolling}/crawler.d.ts +0 -0
  522. package/dist/types/src/extensions/{scrolling → streaming/scrolling}/index.d.ts +0 -0
  523. package/dist/types/src/extensions/{scrolling → streaming/scrolling}/scrollbar-autohide.d.ts +0 -0
  524. package/dist/types/src/extensions/{scrolling → streaming/scrolling}/scroller.d.ts +0 -0
  525. package/dist/types/src/extensions/{typewriter.test.d.ts → streaming/typewriter.test.d.ts} +0 -0
  526. package/dist/types/src/extensions/{folding.d.ts → structure/folding/folding.d.ts} +0 -0
  527. package/dist/types/src/extensions/{outliner → structure/outliner}/editor.d.ts +0 -0
  528. package/dist/types/src/extensions/{outliner → structure/outliner}/editor.test.d.ts +0 -0
  529. package/dist/types/src/extensions/{outliner → structure/outliner}/outliner.d.ts +0 -0
  530. package/dist/types/src/extensions/{outliner → structure/outliner}/outliner.test.d.ts +0 -0
  531. package/dist/types/src/extensions/{outliner → structure/outliner}/tree.test.d.ts +0 -0
  532. package/src/extensions/{dnd.ts → behavior/dnd.ts} +29 -29
  533. package/src/extensions/{awareness → collab/awareness}/index.ts +0 -0
  534. package/src/extensions/{factories.test.ts → core/factories.test.ts} +0 -0
  535. package/src/extensions/{replacer.test.ts → decoration/replacer.test.ts} +0 -0
  536. package/src/extensions/{replacer.ts → decoration/replacer.ts} +25 -25
  537. /package/src/extensions/{markdown → language/markdown}/index.ts +0 -0
  538. /package/src/extensions/{tags → language/xml}/index.ts +0 -0
  539. /package/src/extensions/{tags → language/xml}/testing/text.md +0 -0
  540. /package/src/extensions/{tags → language/xml}/testing/text.txt +0 -0
  541. /package/src/extensions/{tags → language/xml}/widgets/anchor.ts +0 -0
  542. /package/src/extensions/{tags → language/xml}/widgets/index.ts +0 -0
  543. /package/src/extensions/{tags → language/xml}/xml-util.ts +0 -0
  544. /package/src/extensions/{modal.ts → state/modal.ts} +0 -0
  545. /package/src/extensions/{selection.test.ts → state/selection.test.ts} +0 -0
  546. /package/src/extensions/{pending → streaming/pending}/index.ts +0 -0
  547. /package/src/extensions/{pending → streaming/pending}/pending-text-stream.test.ts +0 -0
  548. /package/src/extensions/{scrolling → streaming/scrolling}/crawler.ts +0 -0
  549. /package/src/extensions/{scrolling → streaming/scrolling}/index.ts +0 -0
  550. /package/src/extensions/{scrolling → streaming/scrolling}/scroller.ts +0 -0
  551. /package/src/extensions/{typewriter.test.ts → streaming/typewriter.test.ts} +0 -0
@@ -0,0 +1,935 @@
1
+ import { EditorSelection, Facet, StateEffect, StateField, Text, Transaction } from "@codemirror/state";
2
+ import { Decoration, EditorView, RectangleMarker, ViewPlugin, keymap, layer } from "@codemirror/view";
3
+ import { isNonNullable, isTruthy } from "@dxos/util";
4
+ import * as Schema from "effect/Schema";
5
+ import { debounce } from "@dxos/async";
6
+ import { log } from "@dxos/log";
7
+ import { invertedEffects } from "@codemirror/commands";
8
+ import { Chunk, getChunks, unifiedMergeView } from "@codemirror/merge";
9
+ import sortBy from "lodash.sortby";
10
+ import { diffWordsWithSpace } from "diff";
11
+ //#region src/util/facet.ts
12
+ var singleValueFacet = (defaultValue) => Facet.define({ combine: (providers) => {
13
+ return providers[0] ?? defaultValue;
14
+ } });
15
+ //#endregion
16
+ //#region src/util/cursor.ts
17
+ /**
18
+ * Determines if two ranges overlap.
19
+ * A range is considered to overlap if there is any intersection
20
+ * between the two ranges, inclusive of their boundaries.
21
+ */
22
+ var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
23
+ var defaultCursorConverter = {
24
+ toCursor: (position) => position.toString(),
25
+ fromCursor: (cursor) => parseInt(cursor)
26
+ };
27
+ var Cursor = class Cursor {
28
+ static converter = singleValueFacet(defaultCursorConverter);
29
+ static getCursorFromRange = (state, range) => {
30
+ const cursorConverter = state.facet(Cursor.converter);
31
+ return [cursorConverter.toCursor(range.from), cursorConverter.toCursor(range.to, -1)].join(":");
32
+ };
33
+ static getRangeFromCursor = (state, cursor) => {
34
+ const cursorConverter = state.facet(Cursor.converter);
35
+ const parts = cursor.split(":");
36
+ const from = cursorConverter.fromCursor(parts[0]);
37
+ const to = cursorConverter.fromCursor(parts[1]);
38
+ return from !== void 0 && to !== void 0 ? {
39
+ from,
40
+ to
41
+ } : void 0;
42
+ };
43
+ };
44
+ //#endregion
45
+ //#region src/util/debug.ts
46
+ var __dxlog_file$1 = "/__w/dxos/dxos/packages/ui/ui-editor/src/util/debug.ts";
47
+ var join = (...lines) => lines.join("\n");
48
+ /**
49
+ * CodeMirror callbacks swallow errors so wrap handlers.
50
+ */
51
+ var wrapWithCatch = (fn, label) => {
52
+ return (...args) => {
53
+ try {
54
+ return fn(...args);
55
+ } catch (err) {
56
+ log.catch(err, { label }, {
57
+ "~LogMeta": "~LogMeta",
58
+ F: __dxlog_file$1,
59
+ L: 20,
60
+ S: void 0
61
+ });
62
+ }
63
+ };
64
+ };
65
+ /**
66
+ * Log all changes before dispatching them to the view.
67
+ * https://codemirror.net/docs/ref/#view.EditorView.dispatch
68
+ */
69
+ var debugDispatcher = (trs, view) => {
70
+ logChanges(trs);
71
+ view.update(trs);
72
+ };
73
+ /**
74
+ * Util to log transactions in update listener.
75
+ */
76
+ var logChanges = (trs) => {
77
+ const changes = trs.flatMap((tr) => {
78
+ if (tr.changes.empty) return;
79
+ const changes = [];
80
+ tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes.push(JSON.stringify({
81
+ fromA,
82
+ toA,
83
+ fromB,
84
+ toB,
85
+ inserted: inserted.toString()
86
+ })));
87
+ return changes;
88
+ }).filter(Boolean);
89
+ if (changes.length) log("changes", { changes }, {
90
+ "~LogMeta": "~LogMeta",
91
+ F: __dxlog_file$1,
92
+ L: 54,
93
+ S: void 0
94
+ });
95
+ };
96
+ //#endregion
97
+ //#region src/extensions/state/selection.ts
98
+ /**
99
+ * Currently edited document id as FQ string.
100
+ */
101
+ var documentId = singleValueFacet();
102
+ var EditorSelection$1 = Schema.Struct({
103
+ anchor: Schema.Number,
104
+ head: Schema.optional(Schema.Number)
105
+ }).pipe(Schema.mutable);
106
+ var EditorSelectionStateSchema = Schema.Struct({
107
+ scrollTo: Schema.optional(Schema.Number),
108
+ selection: Schema.optional(EditorSelection$1)
109
+ }).pipe(Schema.mutable);
110
+ var stateRestoreAnnotation = "org.dxos.cm.state-restore";
111
+ var createEditorStateTransaction = ({ scrollTo, selection }) => {
112
+ return {
113
+ selection,
114
+ scrollIntoView: !scrollTo,
115
+ effects: scrollTo ? EditorView.scrollIntoView(scrollTo, { yMargin: 96 }) : void 0,
116
+ annotations: Transaction.userEvent.of(stateRestoreAnnotation)
117
+ };
118
+ };
119
+ /**
120
+ * Track scrolling and selection state to be restored when switching to document.
121
+ */
122
+ var selectionState = ({ getState, setState } = {}) => {
123
+ const setStateDebounced = debounce(setState, 1e3);
124
+ return [EditorView.updateListener.of(({ view, transactions }) => {
125
+ const id = view.state.facet(documentId);
126
+ if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) return;
127
+ if (setState) {
128
+ const { scrollTop } = view.scrollDOM;
129
+ const pos = view.posAtCoords({
130
+ x: 0,
131
+ y: scrollTop
132
+ });
133
+ if (pos !== null) {
134
+ const { anchor, head } = view.state.selection.main;
135
+ setStateDebounced(id, {
136
+ scrollTo: pos,
137
+ selection: {
138
+ anchor,
139
+ head
140
+ }
141
+ });
142
+ }
143
+ }
144
+ }), getState && keymap.of([{
145
+ key: "Ctrl-r",
146
+ run: (view) => {
147
+ const state = getState(view.state.facet(documentId));
148
+ if (state && (state.scrollTo != null || state.selection)) view.dispatch(createEditorStateTransaction(state));
149
+ return true;
150
+ }
151
+ }])].filter(isTruthy);
152
+ };
153
+ //#endregion
154
+ //#region src/extensions/review/comments.ts
155
+ var __dxlog_file = "/__w/dxos/dxos/packages/ui/ui-editor/src/extensions/review/comments.ts";
156
+ /**
157
+ * Comment threads.
158
+ * 1). Updates the EditorModel to store relative selections for a set of comments threads.
159
+ * Since the selections are relative, they do not need to be updated when the document is edited.
160
+ * 2). Implements a StateField to track absolute selections corresponding to the comments (i.e., when the document is edited).
161
+ * 3). Creates decoration marks to apply classes to each selection.
162
+ * 4). Tracks the current cursor position to:
163
+ * a). Update the decoration to show if the cursor is within a current selection.
164
+ * b). Calls a handler to indicate which is the closest selection (e.g., to update the thread sidebar).
165
+ * 5). Optionally, implements a hoverTooltip to show hints when creating a selection range.
166
+ */
167
+ var comments = (options) => {
168
+ const { key: shortcut = "meta-'" } = options;
169
+ const handleSelect = debounce((state) => options.onSelect?.(state), 200);
170
+ return [
171
+ optionsFacet.of(options),
172
+ options.id ? documentId.of(options.id) : void 0,
173
+ commentsState,
174
+ commentsDecorations,
175
+ commentsHighlightLayer,
176
+ handleCommentClick,
177
+ styles,
178
+ ViewPlugin.fromClass(class {
179
+ unsubscribe;
180
+ constructor(view) {
181
+ const { id } = options;
182
+ const updateComments = () => {
183
+ const comments = options.getComments?.() ?? [];
184
+ if (id && id === view.state.facet(documentId)) queueMicrotask(() => view.dispatch({ effects: setComments.of({
185
+ id,
186
+ comments
187
+ }) }));
188
+ };
189
+ this.unsubscribe = options.subscribe?.(updateComments) ?? (() => {});
190
+ updateComments();
191
+ }
192
+ destroy = () => {
193
+ this.unsubscribe();
194
+ };
195
+ }),
196
+ options.onCreate && keymap.of([{
197
+ key: shortcut,
198
+ run: wrapWithCatch(createComment)
199
+ }]),
200
+ EditorView.updateListener.of(({ view, state, changes }) => {
201
+ let mod = false;
202
+ const { comments, ...value } = state.field(commentsState);
203
+ changes.iterChanges((from, to, from2, to2) => {
204
+ comments.forEach(({ comment, range }) => {
205
+ if (!comment.cursor) return;
206
+ if (from2 === to2) {
207
+ const newRange = Cursor.getRangeFromCursor(view.state, comment.cursor);
208
+ if (!newRange || newRange.to - newRange.from === 0) options.onDelete?.({ id: comment.id });
209
+ }
210
+ if (from <= range.to) {
211
+ const newRange = Cursor.getRangeFromCursor(view.state, comment.cursor);
212
+ Object.assign(range, newRange);
213
+ mod = true;
214
+ }
215
+ });
216
+ });
217
+ if (mod) view.dispatch({ effects: setCommentState.of({
218
+ comments,
219
+ ...value
220
+ }) });
221
+ }),
222
+ EditorView.updateListener.of(({ view, state, transactions }) => {
223
+ let min = Infinity;
224
+ const { selection: applied, comments } = state.field(commentsState);
225
+ const { current, closest } = applied;
226
+ const notify = (selection) => handleSelect({
227
+ selection,
228
+ id: state.facet(documentId),
229
+ comments: comments.map(({ comment, range }) => ({
230
+ comment,
231
+ range,
232
+ location: view.coordsAtPos(range.from)
233
+ }))
234
+ });
235
+ if (transactions.some((tr) => tr.effects.some((effect) => effect.is(setSelection)))) {
236
+ notify(applied);
237
+ return;
238
+ }
239
+ const { head } = state.selection.main;
240
+ const selection = {};
241
+ comments.forEach(({ comment, range }) => {
242
+ if (head >= range.from && head <= range.to) {
243
+ selection.current = comment.id;
244
+ selection.closest = void 0;
245
+ }
246
+ if (!selection.current) {
247
+ const d = Math.min(Math.abs(head - range.from), Math.abs(head - range.to));
248
+ if (d < min) {
249
+ selection.closest = comment.id;
250
+ min = d;
251
+ }
252
+ }
253
+ });
254
+ if (selection.current !== current || selection.closest !== closest) {
255
+ view.dispatch({ effects: setSelection.of(selection) });
256
+ notify(selection);
257
+ }
258
+ }),
259
+ options.onUpdate && trackPastedComments(options.onUpdate)
260
+ ].filter(isNonNullable);
261
+ };
262
+ var setComments = StateEffect.define();
263
+ var setSelection = StateEffect.define();
264
+ var setCommentState = StateEffect.define();
265
+ /**
266
+ * State field (reducer) that tracks comment ranges.
267
+ * The ranges are tracked as Automerge cursors from which the absolute indexed ranges can be computed.
268
+ * Included by {@link comments}; exported for direct state reads.
269
+ */
270
+ var commentsState = StateField.define({
271
+ create: (state) => ({
272
+ id: state.facet(documentId),
273
+ comments: [],
274
+ selection: {}
275
+ }),
276
+ update: (value, tr) => {
277
+ for (const effect of tr.effects) {
278
+ if (effect.is(setSelection)) return {
279
+ ...value,
280
+ selection: effect.value
281
+ };
282
+ if (effect.is(setComments)) {
283
+ const { comments } = effect.value;
284
+ const commentStates = comments.map((comment) => {
285
+ if (!comment.cursor) return;
286
+ const range = Cursor.getRangeFromCursor(tr.state, comment.cursor);
287
+ return range && {
288
+ comment,
289
+ range
290
+ };
291
+ }).filter(isNonNullable);
292
+ return {
293
+ ...value,
294
+ comments: commentStates
295
+ };
296
+ }
297
+ if (effect.is(setCommentState)) return effect.value;
298
+ }
299
+ return value;
300
+ }
301
+ });
302
+ var createCommentMark = (id, isCurrent) => Decoration.mark({
303
+ class: "cm-comment",
304
+ attributes: {
305
+ "data-testid": "cm-comment",
306
+ "data-comment-id": id,
307
+ "data-current": isCurrent ? "1" : "0"
308
+ }
309
+ });
310
+ /**
311
+ * Transparent inline marks that carry `data-comment-id` for click routing (see `handleCommentClick`).
312
+ * The colour comes from `commentsHighlightLayer`.
313
+ */
314
+ var commentsDecorations = EditorView.decorations.compute([commentsState], (state) => {
315
+ const { selection: { current }, comments } = state.field(commentsState);
316
+ const decorations = sortBy(comments ?? [], (range) => range.range.from)?.flatMap((comment) => {
317
+ const range = comment.range;
318
+ if (!range) {
319
+ log.warn("Invalid range:", range, {
320
+ "~LogMeta": "~LogMeta",
321
+ F: __dxlog_file,
322
+ L: 342,
323
+ S: void 0
324
+ });
325
+ return;
326
+ } else if (range.from === range.to) return;
327
+ return createCommentMark(comment.comment.id, comment.comment.id === current).range(range.from, range.to);
328
+ }).filter(isNonNullable);
329
+ return Decoration.set(decorations);
330
+ });
331
+ /**
332
+ * Selection-style highlight: draws each comment range as a layer of rectangle markers below the text.
333
+ * `RectangleMarker.forRange` extends wrapped (non-final) lines to the line edge, so a multi-line comment
334
+ * reads as one continuous block rather than ragged per-word inline backgrounds.
335
+ */
336
+ var commentsHighlightLayer = layer({
337
+ above: false,
338
+ class: "cm-commentsHighlightLayer",
339
+ update: (update) => update.docChanged || update.viewportChanged || update.geometryChanged || update.selectionSet || update.transactions.some((tr) => tr.effects.some((effect) => effect.is(setSelection) || effect.is(setComments) || effect.is(setCommentState))),
340
+ markers: (view) => {
341
+ const { selection: { current }, comments } = view.state.field(commentsState);
342
+ return sortBy(comments ?? [], (comment) => comment.range.from).flatMap((comment) => {
343
+ const { from, to } = comment.range;
344
+ if (from >= to) return [];
345
+ const className = comment.comment.id === current ? "cm-comment-highlight cm-comment-highlight-current" : "cm-comment-highlight";
346
+ const range = EditorSelection.range(from, to);
347
+ const markers = RectangleMarker.forRange(view, className, range);
348
+ return markers.length === 1 ? RectangleMarker.forRange(view, `${className} cm-comment-highlight-single`, range) : markers;
349
+ });
350
+ }
351
+ });
352
+ var handleCommentClick = EditorView.domEventHandlers({ click: (event, view) => {
353
+ const id = commentIdAtClick(event, view);
354
+ if (!id) return false;
355
+ scrollCommentIntoView(view, id);
356
+ view.state.facet(optionsFacet).onActivate?.(id);
357
+ return true;
358
+ } });
359
+ /**
360
+ * Resolve the comment id under a click. Prefers the DOM target (a direct hit on the `.cm-comment`
361
+ * span), then falls back to a document-position hit-test: the highlight-layer rectangles
362
+ * (pointer-events: none) sit over the text, so a click often lands on the `.cm-line` (an ancestor of
363
+ * the span) and an upward target walk would miss it.
364
+ */
365
+ var commentIdAtClick = (event, view) => {
366
+ let target = event.target;
367
+ const editorRoot = view.dom;
368
+ while (target && target !== editorRoot && !target.hasAttribute?.("data-comment-id")) target = target.parentElement;
369
+ const domId = target && target !== editorRoot ? target.getAttribute("data-comment-id") : null;
370
+ if (domId) return domId;
371
+ const pos = view.posAtCoords({
372
+ x: event.clientX,
373
+ y: event.clientY
374
+ });
375
+ if (pos != null) return view.state.field(commentsState, false)?.comments.find(({ range }) => pos >= range.from && pos <= range.to)?.comment.id;
376
+ };
377
+ var trackPastedComments = (onUpdate) => {
378
+ let tracked = null;
379
+ const handleTrack = (event, view) => {
380
+ const comments = view.state.field(commentsState);
381
+ const { main } = view.state.selection;
382
+ const selectedRanges = comments.comments.filter(({ range }) => range.from >= main.from && range.to <= main.to && range.from < range.to);
383
+ if (!selectedRanges.length) tracked = null;
384
+ else tracked = {
385
+ text: view.state.doc.slice(main.from, main.to),
386
+ comments: selectedRanges.map(({ comment, range }) => ({
387
+ id: comment.id,
388
+ from: range.from - main.from,
389
+ to: range.to - main.from
390
+ }))
391
+ };
392
+ };
393
+ return [
394
+ EditorView.domEventHandlers({
395
+ cut: handleTrack,
396
+ copy: handleTrack
397
+ }),
398
+ invertedEffects.of((tr) => {
399
+ const { comments } = tr.startState.field(commentsState);
400
+ const effects = [];
401
+ tr.changes.iterChangedRanges((fromA, toA) => {
402
+ for (const { comment: { id }, range: { from, to } } of comments) if (from < to && from >= fromA && to <= toA) effects.push(restoreCommentEffect.of({
403
+ id,
404
+ from,
405
+ to
406
+ }));
407
+ });
408
+ return effects;
409
+ }),
410
+ EditorView.updateListener.of((update) => {
411
+ const restore = [];
412
+ for (let i = 0; i < update.transactions.length; i++) {
413
+ const tr = update.transactions[i];
414
+ for (let j = 0; j < restore.length; j++) restore[j] = mapTrackedComment(restore[j], tr.changes);
415
+ for (const effect of tr.effects) if (effect.is(restoreCommentEffect)) restore.push(effect.value);
416
+ }
417
+ if (tracked) {
418
+ const paste = update.transactions.find((tr) => tr.isUserEvent("input.paste"));
419
+ if (paste) {
420
+ let found = -1;
421
+ paste.changes.iterChanges((fromA, toA, fromB, toB, text) => {
422
+ if (text.eq(tracked.text)) {
423
+ for (let i = update.transactions.indexOf(paste) + 1; i < update.transactions.length; i++) fromB = update.transactions[i].changes.mapPos(fromB);
424
+ found = fromB;
425
+ }
426
+ });
427
+ if (found > -1) for (const moved of tracked.comments) restore.push({
428
+ id: moved.id,
429
+ from: found + moved.from,
430
+ to: found + moved.to
431
+ });
432
+ tracked = null;
433
+ }
434
+ }
435
+ for (const comment of restore) {
436
+ const { comments } = update.startState.field(commentsState);
437
+ if (!comments.some((c) => c.comment.id === comment.id && c.range.from < c.range.to)) {
438
+ const cursor = Cursor.getCursorFromRange(update.state, comment);
439
+ onUpdate({
440
+ id: comment.id,
441
+ cursor
442
+ });
443
+ }
444
+ }
445
+ })
446
+ ];
447
+ };
448
+ var mapTrackedComment = (comment, changes) => ({
449
+ id: comment.id,
450
+ from: changes.mapPos(comment.from, 1),
451
+ to: changes.mapPos(comment.to, 1)
452
+ });
453
+ /**
454
+ * These are attached to undone/redone transactions in the editor for the purpose of restoring comments
455
+ * that were deleted by the original changes.
456
+ */
457
+ var restoreCommentEffect = StateEffect.define({ map: mapTrackedComment });
458
+ var optionsFacet = singleValueFacet();
459
+ /**
460
+ * Create comment thread action.
461
+ */
462
+ var createComment = (view) => {
463
+ const options = view.state.facet(optionsFacet);
464
+ if (options.readonly) return false;
465
+ let { from, to } = view.state.selection.main;
466
+ const chunk = getChunks(view.state)?.chunks.find((candidate) => candidate.fromB <= to && candidate.endB >= from);
467
+ if (chunk) {
468
+ from = chunk.fromB;
469
+ to = Math.min(chunk.endB, view.state.doc.length);
470
+ } else if (from === to) {
471
+ const word = view.state.wordAt(from);
472
+ if (word) {
473
+ from = word.from;
474
+ to = word.to;
475
+ }
476
+ }
477
+ while (to > from && view.state.doc.sliceString(to - 1, to) === "\n") to--;
478
+ if (from === to) return false;
479
+ const cursor = Cursor.getCursorFromRange(view.state, {
480
+ from,
481
+ to
482
+ });
483
+ if (cursor) {
484
+ view.dispatch({ selection: { anchor: from } });
485
+ options.onCreate?.({
486
+ cursor,
487
+ from,
488
+ location: view.coordsAtPos(from),
489
+ branch: options.reviewBranch
490
+ });
491
+ return true;
492
+ }
493
+ return false;
494
+ };
495
+ /**
496
+ * Whether the [from, to] document range is entirely within the editor's scroll
497
+ * viewport. Returns false if either endpoint isn't currently rendered (off-screen).
498
+ */
499
+ var isRangeVisible = (view, range) => {
500
+ const from = view.coordsAtPos(range.from);
501
+ const to = view.coordsAtPos(range.to);
502
+ if (!from || !to) return false;
503
+ const { top, bottom } = view.scrollDOM.getBoundingClientRect();
504
+ return from.top >= top && to.bottom <= bottom;
505
+ };
506
+ /**
507
+ * Scroll the comment thread with the given id into view (if not already entirely
508
+ * visible) and mark it the current comment so the editor highlights it.
509
+ */
510
+ var scrollCommentIntoView = (view, id, { y = "center", yMargin } = {}) => {
511
+ const comment = view.state.field(commentsState).comments.find((range) => range.comment.id === id);
512
+ if (!comment?.comment.cursor) return;
513
+ const range = Cursor.getRangeFromCursor(view.state, comment.comment.cursor);
514
+ if (!range) return;
515
+ const { from, to } = view.state.selection.main;
516
+ const needsSelectionUpdate = from === to && from !== range.from;
517
+ view.dispatch({
518
+ selection: needsSelectionUpdate ? { anchor: range.from } : void 0,
519
+ effects: [isRangeVisible(view, range) ? [] : EditorView.scrollIntoView(range.from, {
520
+ y,
521
+ yMargin
522
+ }), setSelection.of({ current: id })].flat()
523
+ });
524
+ };
525
+ /**
526
+ * NOTE: Matches search.
527
+ */
528
+ var styles = EditorView.theme({
529
+ ".cm-comment, .cm-comment *": { color: "var(--color-teal-fg) !important" },
530
+ ".cm-comment[data-current=\"1\"], .cm-comment[data-current=\"1\"] *": { color: "var(--color-orange-fg) !important" },
531
+ ".cm-comment": { cursor: "pointer" },
532
+ ".cm-commentsHighlightLayer": { pointerEvents: "none" },
533
+ ".cm-comment-highlight": {
534
+ backgroundColor: "var(--color-teal-bg)",
535
+ boxShadow: "0 0 0 1px var(--color-teal-bg)",
536
+ boxSizing: "content-box",
537
+ marginInline: "-2px",
538
+ paddingInline: "2px",
539
+ pointerEvents: "none"
540
+ },
541
+ ".cm-comment-highlight-current": {
542
+ backgroundColor: "var(--color-orange-bg)",
543
+ boxShadow: "0 0 0 1px var(--color-orange-bg)"
544
+ },
545
+ ".cm-comment-highlight-single": { borderRadius: "0.25rem" }
546
+ });
547
+ //#endregion
548
+ //#region src/extensions/review/diff.ts
549
+ /**
550
+ * Orient the diff as a preview of accepting the original (the compared branch) into the editor's
551
+ * document (the current branch): the compare branch's content — which the merge view renders as
552
+ * deletions because it is absent from the editor — is what accepting ADDS, so show it as an addition;
553
+ * the current branch's deviating content is what accepting REMOVES. This overrides the merge view's
554
+ * default green-editor / red-original colouring, which reads inverted for branch review.
555
+ */
556
+ var reviewOrientationTheme = EditorView.theme({
557
+ "&.cm-merge-b .cm-changedLine, &.cm-merge-b .cm-changedText": { backgroundColor: "var(--color-cm-diff-remove-surface)" },
558
+ "& .cm-deletedChunk, & .cm-deletedChunk .cm-deletedText": {
559
+ backgroundColor: "var(--color-cm-diff-add-surface)",
560
+ textDecoration: "none"
561
+ },
562
+ "&.cm-merge-b .cm-changedLineGutter": { background: "var(--color-cm-diff-remove-gutter)" },
563
+ "& .cm-deletedLineGutter": { background: "var(--color-cm-diff-add-gutter)" }
564
+ });
565
+ /**
566
+ * Inline (unified) diff view: renders the editor's document with insertions and deletions marked
567
+ * relative to {@link DiffOptions.original}. The editor stays editable — edits to the document update
568
+ * the diff against the (static) original live — so it can overlay a live editor to compare the
569
+ * current state against another version (e.g. another branch) without locking editing.
570
+ */
571
+ var diffView = ({ original }) => [unifiedMergeView({
572
+ original,
573
+ mergeControls: false
574
+ }), reviewOrientationTheme];
575
+ /**
576
+ * Groups the word-level diff between `before` and `after` into contiguous {@link DiffHunk}s — each a
577
+ * maximal run of insertions/deletions bounded by unchanged text. Used to render Google-Docs-style
578
+ * suggestions (accept/reject per hunk) over the original document (see {@link suggestChanges}).
579
+ */
580
+ var diffHunks = (before, after) => {
581
+ const hunks = [];
582
+ let position = 0;
583
+ let pending;
584
+ const minimize = (hunk) => {
585
+ const { removed, inserted } = hunk;
586
+ let prefix = 0;
587
+ while (prefix < removed.length && prefix < inserted.length && removed[prefix] === inserted[prefix]) prefix++;
588
+ let suffix = 0;
589
+ while (suffix < removed.length - prefix && suffix < inserted.length - prefix && removed[removed.length - 1 - suffix] === inserted[inserted.length - 1 - suffix]) suffix++;
590
+ if (prefix + suffix !== removed.length && prefix + suffix !== inserted.length) return hunk;
591
+ return {
592
+ from: hunk.from + prefix,
593
+ to: hunk.to - suffix,
594
+ removed: removed.slice(prefix, removed.length - suffix),
595
+ inserted: inserted.slice(prefix, inserted.length - suffix)
596
+ };
597
+ };
598
+ const flush = () => {
599
+ if (pending) {
600
+ hunks.push(minimize(pending));
601
+ pending = void 0;
602
+ }
603
+ };
604
+ for (const change of diffWordsWithSpace(before, after)) if (change.added) {
605
+ pending ??= {
606
+ from: position,
607
+ to: position,
608
+ removed: "",
609
+ inserted: ""
610
+ };
611
+ pending.inserted += change.value;
612
+ } else if (change.removed) {
613
+ pending ??= {
614
+ from: position,
615
+ to: position,
616
+ removed: "",
617
+ inserted: ""
618
+ };
619
+ pending.removed += change.value;
620
+ pending.to = position + change.value.length;
621
+ position += change.value.length;
622
+ } else {
623
+ flush();
624
+ position += change.value.length;
625
+ }
626
+ flush();
627
+ return hunks;
628
+ };
629
+ var groupHunks = (hunks, before, policy = {}) => {
630
+ const { maxGap = 0, respectBlockBoundaries = true } = policy;
631
+ const groups = [];
632
+ for (const hunk of hunks) {
633
+ const previous = groups.at(-1);
634
+ const gap = previous ? before.slice(previous.to, hunk.from) : "";
635
+ if (previous !== void 0 && gap.length <= maxGap && !(respectBlockBoundaries && /\n[ \t]*\n/.test(gap))) {
636
+ previous.to = hunk.to;
637
+ previous.removed += gap + hunk.removed;
638
+ previous.inserted += gap + hunk.inserted;
639
+ } else groups.push({ ...hunk });
640
+ }
641
+ return groups;
642
+ };
643
+ /** Markdown delimiter pairs that must be suggested — and applied — atomically. */
644
+ var MARKUP_DELIMITERS = /* @__PURE__ */ new Set([
645
+ "**",
646
+ "__",
647
+ "*",
648
+ "_",
649
+ "~~",
650
+ "`"
651
+ ]);
652
+ /**
653
+ * Coalesces two pure insertions forming a matched markdown delimiter pair around intervening text
654
+ * (e.g. `**` before and after a phrase) into ONE replace hunk spanning the wrapped text. Without
655
+ * this, wrapping MULTIPLE words diffs as two zero-width inserts, and accepting either half alone
656
+ * leaves broken syntax. Only a tight wrap (same line, non-empty gap) reads as one formatting action.
657
+ */
658
+ var pairMarkupHunks = (hunks, before) => {
659
+ const result = [];
660
+ for (let index = 0; index < hunks.length; index++) {
661
+ const open = hunks[index];
662
+ const close = hunks[index + 1];
663
+ if (close !== void 0 && open.from === open.to && close.from === close.to && close.from > open.from && MARKUP_DELIMITERS.has(open.inserted) && close.inserted === open.inserted) {
664
+ const gap = before.slice(open.from, close.from);
665
+ if (gap.length > 0 && !gap.includes("\n")) {
666
+ result.push({
667
+ from: open.from,
668
+ to: close.from,
669
+ removed: gap,
670
+ inserted: open.inserted + gap + close.inserted
671
+ });
672
+ index++;
673
+ continue;
674
+ }
675
+ }
676
+ result.push(open);
677
+ }
678
+ return result;
679
+ };
680
+ /**
681
+ * Re-anchors {@link DiffHunk}s computed against `base` into `doc` coordinates, so a foreign author's
682
+ * proposal (diffed `base` vs proposal) can be decorated over a `doc` that has itself diverged from
683
+ * `base` (the user's own branch edits). Each hunk offset is mapped through the character-level
684
+ * `base`↔`doc` diff ({@link computeCharHunks}): a position in an unchanged region shifts by the net
685
+ * length of edits before it; a position inside a doc-edited region clamps to that region's edge (the
686
+ * `from` to its start, the `to` to its end). Without this, a proposal diffed against `base` would
687
+ * render at stale offsets over the diverged `doc`.
688
+ */
689
+ var rebaseHunks = (base, doc, hunks) => rebaseHunksWith(computeCharHunks(base, doc), hunks);
690
+ /**
691
+ * {@link rebaseHunks} with a precomputed `base`↔`doc` character diff. Callers rebasing MANY hunk sets
692
+ * against the same pair — e.g. every author's proposal over one branch (see {@link suggestions}) —
693
+ * compute {@link computeCharHunks} once and reuse it, rather than re-diffing the whole document per set.
694
+ */
695
+ var rebaseHunksWith = (charHunks, hunks) => {
696
+ const mapPos = (pos, side) => {
697
+ let delta = 0;
698
+ for (const hunk of charHunks) {
699
+ if (pos < hunk.fromA) break;
700
+ if (pos === hunk.fromA) return hunk.fromB;
701
+ if (pos < hunk.toA) return side < 0 ? hunk.fromB : hunk.toB;
702
+ delta = hunk.toB - hunk.toA;
703
+ }
704
+ return pos + delta;
705
+ };
706
+ return hunks.map((hunk) => {
707
+ if (hunk.from === hunk.to) {
708
+ const at = mapPos(hunk.from, -1);
709
+ return {
710
+ ...hunk,
711
+ from: at,
712
+ to: at
713
+ };
714
+ }
715
+ return {
716
+ ...hunk,
717
+ from: mapPos(hunk.from, -1),
718
+ to: mapPos(hunk.to, 1)
719
+ };
720
+ });
721
+ };
722
+ /**
723
+ * LINE-level changed hunks between `original` (A) and `modified` (B) as character ranges (via
724
+ * `@codemirror/merge` `Chunk.build`). Coarser than {@link computeWordHunks}; retained for callers that
725
+ * want whole-line change regions.
726
+ */
727
+ var computeHunks = (original, modified) => Chunk.build(Text.of(original.split("\n")), Text.of(modified.split("\n"))).map((chunk) => ({
728
+ fromA: chunk.fromA,
729
+ toA: chunk.toA,
730
+ fromB: chunk.fromB,
731
+ toB: chunk.toB
732
+ }));
733
+ /**
734
+ * WORD-level changed hunks between `original` (A) and `modified` (B), each carrying both coordinate
735
+ * ranges. Matches the word granularity of {@link diffHunks} (same `diffWordsWithSpace` alignment), so
736
+ * {@link cherryPickHunk} / {@link revertHunk} resolve exactly the anchored word(s) — accepting one
737
+ * word does not pull in the rest of its line.
738
+ */
739
+ var computeWordHunks = (original, modified) => {
740
+ const hunks = [];
741
+ let positionA = 0;
742
+ let positionB = 0;
743
+ let pending;
744
+ const flush = () => {
745
+ if (pending) {
746
+ hunks.push(pending);
747
+ pending = void 0;
748
+ }
749
+ };
750
+ for (const change of diffWordsWithSpace(original, modified)) if (change.added) {
751
+ pending ??= {
752
+ fromA: positionA,
753
+ toA: positionA,
754
+ fromB: positionB,
755
+ toB: positionB
756
+ };
757
+ positionB += change.value.length;
758
+ pending.toB = positionB;
759
+ } else if (change.removed) {
760
+ pending ??= {
761
+ fromA: positionA,
762
+ toA: positionA,
763
+ fromB: positionB,
764
+ toB: positionB
765
+ };
766
+ positionA += change.value.length;
767
+ pending.toA = positionA;
768
+ } else {
769
+ flush();
770
+ positionA += change.value.length;
771
+ positionB += change.value.length;
772
+ }
773
+ flush();
774
+ return hunks;
775
+ };
776
+ /**
777
+ * CHARACTER-level changed hunks between `original` (A) and `modified` (B), each carrying both
778
+ * coordinate ranges. Finer than {@link computeWordHunks}: an in-word or whitespace/newline edit shows
779
+ * only the changed characters, not a whole-word delete+insert. Used for live "Suggesting mode" tracked
780
+ * changes (see {@link trackChanges}), where word granularity makes every keystroke read as a struck
781
+ * word rebuilt beside it.
782
+ */
783
+ var computeCharHunks = (original, modified) => joinNearbyHunks(wordHunks(original, modified)).map((hunk) => trimCommonAffixes(original, modified, hunk)).map((hunk) => slideToWordBoundary(original, modified, hunk));
784
+ /**
785
+ * Unchanged text shorter than this between two changed regions does not separate them: a selection
786
+ * that cuts into the words at each end leaves a word fragment on both sides of a single space, and
787
+ * reporting those as two changes strikes text the reader never touched.
788
+ */
789
+ var MIN_COMMON_RUN = 4;
790
+ /** Merges hunks separated by less unchanged text than {@link MIN_COMMON_RUN}, absorbing the gap. */
791
+ var joinNearbyHunks = (hunks) => {
792
+ const merged = [];
793
+ for (const hunk of hunks) {
794
+ const previous = merged.at(-1);
795
+ if (previous && hunk.fromA - previous.toA < MIN_COMMON_RUN && hunk.fromB - previous.toB < MIN_COMMON_RUN) {
796
+ previous.toA = hunk.toA;
797
+ previous.toB = hunk.toB;
798
+ } else merged.push({ ...hunk });
799
+ }
800
+ return merged;
801
+ };
802
+ /** Accumulates a diff's changed regions into {@link Hunk}s, given a tokenisation of the two texts. */
803
+ var accumulate = (changes) => {
804
+ const hunks = [];
805
+ let positionA = 0;
806
+ let positionB = 0;
807
+ let pending;
808
+ const flush = () => {
809
+ if (pending) {
810
+ hunks.push(pending);
811
+ pending = void 0;
812
+ }
813
+ };
814
+ for (const change of changes) if (change.added) {
815
+ pending ??= {
816
+ fromA: positionA,
817
+ toA: positionA,
818
+ fromB: positionB,
819
+ toB: positionB
820
+ };
821
+ positionB += change.value.length;
822
+ pending.toB = positionB;
823
+ } else if (change.removed) {
824
+ pending ??= {
825
+ fromA: positionA,
826
+ toA: positionA,
827
+ fromB: positionB,
828
+ toB: positionB
829
+ };
830
+ positionA += change.value.length;
831
+ pending.toA = positionA;
832
+ } else {
833
+ flush();
834
+ positionA += change.value.length;
835
+ positionB += change.value.length;
836
+ }
837
+ flush();
838
+ return hunks;
839
+ };
840
+ var wordHunks = (original, modified) => accumulate(diffWordsWithSpace(original, modified));
841
+ /**
842
+ * Shrinks a word-level hunk to the characters that actually changed, by dropping the prefix and suffix
843
+ * its two sides share. Word granularity is what keeps one edit from fragmenting into strikes with
844
+ * untouched letters marooned between them, but on its own it reports whole words: a deletion cutting
845
+ * into the words at each end fuses the survivors, and the hunk then reads as "delete both words, insert
846
+ * this fused one". Trimming leaves exactly the range the reader removed (or typed).
847
+ */
848
+ var trimCommonAffixes = (original, modified, hunk) => {
849
+ const removed = original.slice(hunk.fromA, hunk.toA);
850
+ const inserted = modified.slice(hunk.fromB, hunk.toB);
851
+ const limit = Math.min(removed.length, inserted.length);
852
+ let prefix = 0;
853
+ while (prefix < limit && removed[prefix] === inserted[prefix]) prefix++;
854
+ let suffix = 0;
855
+ while (suffix < limit - prefix && removed[removed.length - 1 - suffix] === inserted[inserted.length - 1 - suffix]) suffix++;
856
+ return {
857
+ fromA: hunk.fromA + prefix,
858
+ toA: hunk.toA - suffix,
859
+ fromB: hunk.fromB + prefix,
860
+ toB: hunk.toB - suffix
861
+ };
862
+ };
863
+ /**
864
+ * Slides a one-sided hunk (a pure deletion or insertion) to the word boundary that encloses it. Which
865
+ * characters a one-sided edit removed is ambiguous whenever text repeats around it: deleting
866
+ * `suggest change` from `suggest changes` leaves an `s` that is equally the head of the first word or
867
+ * the tail of the last, and the minimal-edit answer strikes `uggest changes` — keeping a letter of the
868
+ * word the reader deleted. Rotating the span while it still describes the same edit lets it settle
869
+ * where a reader would draw it.
870
+ */
871
+ var slideToWordBoundary = (original, modified, hunk) => {
872
+ const deletion = hunk.toB === hunk.fromB;
873
+ if (deletion === (hunk.toA === hunk.fromA)) return hunk;
874
+ const text = deletion ? original : modified;
875
+ const from = deletion ? hunk.fromA : hunk.fromB;
876
+ const to = deletion ? hunk.toA : hunk.toB;
877
+ const atBoundary = (offset) => offset === 0 || /\s/.test(text[offset - 1]);
878
+ if (atBoundary(from)) return hunk;
879
+ for (let shift = 1; shift <= from; shift++) {
880
+ if (text[from - shift] !== text[to - shift]) break;
881
+ if (atBoundary(from - shift)) return {
882
+ fromA: hunk.fromA - shift,
883
+ toA: hunk.toA - shift,
884
+ fromB: hunk.fromB - shift,
885
+ toB: hunk.toB - shift
886
+ };
887
+ }
888
+ return hunk;
889
+ };
890
+ /**
891
+ * Does a hunk cover the anchored range? Half-open, so a range touching a neighbouring hunk's
892
+ * boundary is not on that hunk — except where either side is empty, which is the normal shape of a
893
+ * pure insertion: the inserted text occupies no span on the other side, and the caller anchors it at
894
+ * a single offset. Those collapse to a containment test, or accepting an insertion is impossible.
895
+ */
896
+ var overlaps = (from, to, range) => from === to || range.start === range.end ? from <= range.end && to >= range.start : from < range.end && to > range.start;
897
+ /**
898
+ * Resolve a single change to apply when cherry-picking from `compare` (A) into `current` (B): find
899
+ * the hunk overlapping `range` (a character range in `current`) and return the splice that replaces
900
+ * that hunk's current text with the compare version. Returns undefined if no hunk overlaps the range
901
+ * (e.g. the change was already applied/reverted). `compare` is read live by the caller, so applying
902
+ * the result always reflects the latest diff — not a snapshot.
903
+ */
904
+ var cherryPickHunk = (current, compare, range) => {
905
+ const matched = computeWordHunks(compare, current).filter((h) => overlaps(h.fromB, h.toB, range));
906
+ if (matched.length === 0) return;
907
+ const first = matched[0];
908
+ const last = matched[matched.length - 1];
909
+ return {
910
+ from: first.fromB,
911
+ del: Math.min(last.toB, current.length) - first.fromB,
912
+ insert: compare.slice(first.fromA, Math.min(last.toA, compare.length))
913
+ };
914
+ };
915
+ /**
916
+ * Resolve the splice that reverts a single change on `compare` (a branch) back to `base` (main) —
917
+ * the reject counterpart to {@link cherryPickHunk}. `baseRange` is a character range in `base`; the
918
+ * hunk overlapping it is located and the returned splice (in `compare` coordinates) replaces the
919
+ * branch's version with the base text. Returns undefined if no hunk overlaps the range.
920
+ */
921
+ var revertHunk = (base, compare, baseRange) => {
922
+ const matched = computeWordHunks(base, compare).filter((h) => overlaps(h.fromA, h.toA, baseRange));
923
+ if (matched.length === 0) return;
924
+ const first = matched[0];
925
+ const last = matched[matched.length - 1];
926
+ return {
927
+ from: first.fromB,
928
+ del: Math.min(last.toB, compare.length) - first.fromB,
929
+ insert: base.slice(first.fromA, Math.min(last.toA, base.length))
930
+ };
931
+ };
932
+ //#endregion
933
+ export { singleValueFacet as A, selectionState as C, wrapWithCatch as D, logChanges as E, Cursor as O, documentId as S, join as T, setComments as _, diffHunks as a, EditorSelectionStateSchema as b, pairMarkupHunks as c, revertHunk as d, comments as f, scrollCommentIntoView as g, isRangeVisible as h, computeWordHunks as i, overlap as k, rebaseHunks as l, createComment as m, computeCharHunks as n, diffView as o, commentsState as p, computeHunks as r, groupHunks as s, cherryPickHunk as t, rebaseHunksWith as u, setSelection as v, debugDispatcher as w, createEditorStateTransaction as x, EditorSelection$1 as y };
934
+
935
+ //# sourceMappingURL=chunk-diff.mjs.map